package hy.iot.core.utils;

import cn.hutool.core.exceptions.ExceptionUtil;
import hy.iot.core.annotation.IotField;
import hy.iot.core.exception.FieldFailCodes;
import hy.iot.core.exception.IotFieldException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
public class FieldsUtils {


    public static String getHexStr(String hexStr, IotField fieldHex) {
        int start = fieldHex.hexStart();
        int hexLen = fieldHex.hexLength();
        String hexVo = fieldHex.hexValueOptions();
        int hexVoi = fieldHex.hexValueIndex();
        StringBuffer buffer = new StringBuffer();
        if(StringUtils.isNotBlank(hexVo)){
            if (StringUtils.isNotBlank(hexVo)){
                return hexStr.split(hexVo)[hexVoi];
            }
        }else if (hexLen>0 && (start+hexLen)<hexStr.length()) {
            buffer.append(hexStr.substring(start,hexLen));
            return buffer.toString();
        }
        return buffer.toString();
    }

    public static String getHexStrData(String[] data, IotField fieldHex, int startIndex) {
        int start = fieldHex.hexStart()<1?startIndex:fieldHex.hexStart();
        int hexLen = fieldHex.hexLength();
//        StringBuffer buffer = new StringBuffer();
        StringJoiner joiner = new StringJoiner(fieldHex.concat());
        if (hexLen>0 && (start+hexLen)<=data.length){
            for (int i = start; i < start+hexLen; i++) {
                joiner.add(data[i]);
            }
        }else{
            throw new IotFieldException(1003,"字段解析异常 start: "+ start+" len: "+hexLen);
        }
        String hexVo = fieldHex.hexValueOptions();
        int hexVoi = fieldHex.hexValueIndex();
        if (StringUtils.isNotBlank(hexVo)){
            String[] bt = joiner.toString().split(hexVo);
            return (bt != null && bt.length > hexVoi)?joiner.toString().split(hexVo)[hexVoi]:"";
        }
        return joiner.toString();
    }

    public static void SetField(Field field, Object o, String hex, Object hexValue, String desc) {
        try {
            field.setAccessible(true);
            if (field.getType().getName().equals("java.lang.Double")) {
                field.set(o, Double.valueOf(hexValue+""));
            }
            else {
                field.set(o, hexValue);
            }
        } catch (Exception ex) {
            log.error("{} set field error hex :{} value: {} fieldName: {} exception: {}",desc,hex,hexValue.toString(),field.getName(), ExceptionUtil.stacktraceToString(ex));
        }
    }

    public static List getZoomData(Object result, String[] data, IotField fieldHex, int si) {
//        hext = 当前起始位 , 当前起始位 + 长度 + (可变长度 * 缩放)
        Integer dataLen = Integer.valueOf(result.toString());
        int start = fieldHex.hexStart()<1?si:fieldHex.hexStart();
        Integer startIndex = start +fieldHex.afterZoomNum() + fieldHex.hexLength();
        Integer len = startIndex + (dataLen * fieldHex.zoomNum());
        if (len < data.length) {
            List<Object> list = new ArrayList<>();
            StringJoiner joiner = new StringJoiner(",");
            int index = 0;
            for (int i = startIndex; i < len+1; i++) {
                index++;
                if (index <= fieldHex.zoomNum()){
                    joiner.add(data[i]);
                }else{
                    list.add(joiner.toString());
                    joiner = new StringJoiner(",");
                    index = 1;
                    joiner.add(data[i]);
                }
            }
            return list;
        }
        String se = fieldHex.desc()+" 解析类型: "+fieldHex.parseType().getDesc()+" 缩放值 "+fieldHex.zoomNum();
        throw new IotFieldException(FieldFailCodes.IOT_SCHEMA_PARSE_FAIL,se);
    }
}
